﻿/*-----------------------------------------------------------
// Copyright (C) 2021 Kingerobot
// 版权所有。 
// 文件名：WarehousingBeforeCrnImpl
// 文件功能描述：
// 创建者：名字 (kinger)
// 时间：2023/3/2 11:21:35
// 修改人：
// 时间：
// 修改说明：
// 版本：V1.0.0
//----------------------------------------------------------------*/

namespace KingerRobot.MexicoSailunMDC.SpiService;

[Logging]
internal class WarehousingBeforeCrnImpl: IWarehousingBeforeCrnService
{
    private readonly static IWcsAsrsNetInput _WcsAsrsNetInput = new BWcsAsrsNetInput();
    private readonly static IWcsAsrsCrnInput _WcsAsrsCrnInput = new BWcsAsrsCrnInput();
    private readonly static IRcsEquip _RcsEquip = new BRcsEquip();
    private readonly static ITask _Task = new BTask();
    private readonly static ITaskCmd _TaskCmd = new BTaskCmd();
    private readonly static IWarehousingBeforeService _WarehousingBeforeService = new WarehousingBeforeImpl();
    public long CreateTask(long crnLocId, int lineTaskNo, string remark = "")
    {
        // 获取路线
        var wcsAsrsNetInputs = _WcsAsrsNetInput.GetAsrsNetInputByStartLoc(crnLocId);
        if (!wcsAsrsNetInputs.Any())
        {
            return -5;
        }

        // 可用堆垛机路线
        var crnIds = wcsAsrsNetInputs.Select(t => t.CrnId).ToList();
        var userCrnIds = _RcsEquip.GetWorkEquipByIds(crnIds).Select(t => t.Id).ToList();
        wcsAsrsNetInputs = wcsAsrsNetInputs.Where(t => userCrnIds.Contains(t.CrnId)).ToList();
        if (!wcsAsrsNetInputs.Any())
        {
            return -6;
        }


        // 获取任务数量(未满优先)
        crnIds = wcsAsrsNetInputs.Select(t => t.CrnId).ToList();
        var wcsAsrsCrnInputs = _WcsAsrsCrnInput.GetWcsAsrsCrnInputsByEquipIds(crnIds);
        var taskCount = _Task.GetTaskInputCount(wcsAsrsCrnInputs).Where(t => crnIds.Contains(t.CrnId)).ToList();

        //  查找目标为
        var targetLoc = 0L;
        var resentfulCrn = taskCount.Where(t => t.MaxCount > t.Count).ToList();
        if (resentfulCrn.Any())
        {
            // 任务缓存不满，由远到近入库
            targetLoc = GetTargetLoc(wcsAsrsNetInputs, resentfulCrn);
        }

        if (targetLoc == 0)
        {
            // 任务缓存满，由远到近入库
            var fullCrn = taskCount.Where(t => t.MaxCount <= t.Count).ToList();
            targetLoc = GetTargetLoc(wcsAsrsNetInputs, fullCrn);
        }

        if (targetLoc == 0)
        {
            return -7;
        }
        // 指令结束
        _WarehousingBeforeService.FinishTaskCmd(lineTaskNo, crnLocId);

        // 修改任务
        _Task.UpdateTaskStatusByTaskNo(crnLocId, lineTaskNo, (int)EnumTaskStatus.Executable, remark);

        // 创建指令
        var taskCmd = _TaskCmd.CreateTaskCmd(new()
        {
            TaskNo = lineTaskNo,
            TaskType = (int)EnumTaskType.Transportation,
            StartLoc = crnLocId,
            CurrentLoc = crnLocId,
            TargetLoc = targetLoc,
            CmdStatus = (int)EnumTaskCmdStatus.Executable,
            CmdType = (int)EnumTaskType.Transportation,
        });

        return taskCmd.TaskId.GetValueOrDefault();
    }

    public int ExecuteTask(int taskNo, long locId)
    {
        var task = _Task.GetExecutableTaskByTaskNo(taskNo);
        if (task?.Id is not long taskId)
        {
            return 0;
        }
        var num = _Task.UpdateTaskAndCmdStatus(locId, taskId, (int)EnumTaskStatus.Executed);
        return num;
    }

    private long GetTargetLoc(List<POWcsAsrsNetInput> wcsAsrsNetInputs, List<CrnTaskCount> crnTaskCounts)
    {
        var targetLoc = wcsAsrsNetInputs.Join(crnTaskCounts, f => f.CrnId, s => s.CrnId, (f, s) => new
        {
            NetInput = f,
            Crn = s,
        }).OrderBy(t => t.Crn.Count)
        .ThenByDescending(t => t.NetInput.RelateScore)
        .Select(t => t.NetInput.TargetLoc.GetValueOrDefault())
        .FirstOrDefault();

        return targetLoc;
    }
}

